package com.client.service.impl;

import com.Emplyment.entity.Article;
import com.Emplyment.entity.UserRegister;
import com.Emplyment.enumeration.EmailTemplateEnum;
import com.Emplyment.exception.RegisterException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import com.client.util.EmailApi;
import com.Emplyment.vo.ArticleVo;
import com.Emplyment.vo.ClientUserInfosVo;
import com.alibaba.nacos.common.utils.StringUtils;
import com.client.mapper.ClientUserMapper;
import com.client.service.ClientUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class ClientUserServiceImpl implements ClientUserService {

    @Autowired
    private ClientUserMapper clientUserMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private EmailApi emailApi;

    /**
     * 用户注册
     * @param username
     * @param password
     */
    @Override
    public Integer clientUserRegistration(String username, String password, String email, String verifyCode) {
    if (username == null || password == null || email == null || verifyCode == null){
        log.error("用户名或者密码为空请重新注册");
        return 1;
    }
    BoundHashOperations<String, String, String> hashOperations = stringRedisTemplate.boundHashOps("login:email:captcha:" + email);

        String lastSendTimestamp = hashOperations.get("lastSendTimestamp");
        if (lastSendTimestamp == null){
            return 3;
        }
        long timesTamp = Long.parseLong(lastSendTimestamp);
        long currentTime = System.currentTimeMillis();

        if (currentTime - timesTamp > 60 * 1000 * 5){
            log.error("验证码过期");
            return 2;
        }
        String captcha = hashOperations.get("captcha");
    if (captcha == null || !captcha.equals(verifyCode)){
        log.error("验证码错误,请重新输入");
        return 3;
    }
        //MD5加密算法进行密码加密
    password = DigestUtils.md5DigestAsHex(password.getBytes());
    UserRegister userRegister = clientUserMapper.clientuser(username);

    Integer count =  clientUserMapper.clientuseremail(email);
    if (userRegister != null){
        log.error("用户名已存在,请重新注册");
        return 4;
    }
    if (count > 0){
        log.error("邮箱已存在,请重新注册");
        return 5;
    }

    userRegister = UserRegister.builder()
           .username(username)
           .password(password)
            .email(email)
           .createTime(LocalDateTime.now())
           .build();

    clientUserMapper.insertUser(userRegister);
    return 0;
    }

    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public UserRegister clientUserLogin(String username, String password) {
        if (username == null || password == null){
            throw new RegisterException("用户名，邮箱或者密码为空,请重新登录");
        }
        //MD5加密算法进行密码加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        UserRegister userRegister = clientUserMapper.clientuserlogin(username, password);
        if (userRegister == null){
            userRegister = clientUserMapper.clientemaillogin(username, password);
        }

        if (userRegister == null){
            throw new RegisterException("用户名,邮箱或者密码错误,请重新登录");
        }

        return userRegister;
    }

    @Override
    public ClientUserInfosVo getUserInfo(Long userId) {
        ClientUserInfosVo userInfo = clientUserMapper.getUserInfo(userId);
        return userInfo;
    }

    @Override
    public ArticleVo getCompany(Integer empId) {
        Article company = clientUserMapper.getCompany(empId);
        ArticleVo companyVo = new ArticleVo();
        BeanUtils.copyProperties(company, companyVo);
        return companyVo;
    }

    @Override
    public Integer sendEmail(String email, String code) {
        Integer b = 0;
        if (code.equals("1")) {
            b = sendMailCaptcha("login:email:captcha:" + email, code);
        }else if (code.equals("2")) {
            b = sendMailCaptcha("reset:email:captcha:" + email, code);
        }
        return b;
    }

    @Override
    public Integer resetPassword(String email, String newPassword, String verifyCode) {
        if (newPassword == null || email == null || verifyCode == null){
            log.error("密码或者邮箱或者验证码为空请重新输入");
            return 1;
        }
        BoundHashOperations<String, String, String> hashOperations = stringRedisTemplate.boundHashOps("reset:email:captcha:" + email);

        String lastSendTimestamp = hashOperations.get("lastSendTimestamp");
        if (lastSendTimestamp == null){
            return 3;
        }
        long timesTamp = Long.parseLong(lastSendTimestamp);
        long currentTime = System.currentTimeMillis();

        if (currentTime - timesTamp > 60 * 1000 * 5){
            log.error("验证码过期");
            return 2;
        }
        String captcha = hashOperations.get("captcha");
        if (captcha == null || !captcha.equals(verifyCode)){
            log.error("验证码错误,请重新输入");
            return 3;
        }

        Integer count = clientUserMapper.clientuseremail(email);
        if (count == 0){
            log.error("邮箱不存在,请重新输入");
            return 4;
        }

        //MD5加密算法进行密码加密
        newPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        clientUserMapper.updatePassword(email, newPassword);
        return 0;

    }

    private Integer sendMailCaptcha(String key, String code){
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(key);
        // 初始检查
        String lastSendTimestamp = hashOps.get("lastSendTimestamp");//过期时间
        String sendCount = hashOps.get("sendCount");//发送次数

        if(StringUtils.isNotBlank(sendCount)&&Integer.parseInt(sendCount)>=5){
            hashOps.expire(24, TimeUnit.HOURS);
            return 3;
        }
        if(StringUtils.isNotBlank(lastSendTimestamp)){
            long lastSendTime = Long.parseLong(lastSendTimestamp);
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastSendTime;
            if(elapsedTime < 60 * 1000){
                return 2;
            }
        }
        int newSendCount = StringUtils.isNotBlank(sendCount) ? Integer.parseInt(sendCount) + 1 : 1;
        // 生成验证码
        String captcha = RandomStringUtils.randomNumeric(6);

        try {
            sendCaptcha(key,captcha,code);
        } catch (Exception e) {
            return 4;
        }
        hashOps.put("captcha", captcha);
        hashOps.put("lastSendTimestamp", String.valueOf(System.currentTimeMillis()));
        hashOps.put("sendCount", String.valueOf(newSendCount));
        hashOps.expire(5, TimeUnit.MINUTES); // 设置过期时间为5分钟

        return 1;
    }


    private void sendCaptcha(String hashKey, String captcha, String code){
        if(code.equals("1")) {
            // 根据hashKey判断是发送邮件还是短信，然后调用相应的发送方法
            if ("email".equals(hashKey.split(":")[1])) {
                if (!emailApi.sendHtmlEmail(EmailTemplateEnum.VERIFICATION_CODE_EMAIL_HTML.getSubject(),
                        EmailTemplateEnum.VERIFICATION_CODE_EMAIL_HTML.set(captcha),
                        hashKey.split(":")[3])) {
                    throw new RuntimeException("发送邮件失败");
                }
            }
        } else if (code.equals("2")) {
            if ("email".equals(hashKey.split(":")[1])) {
                if (!emailApi.sendHtmlEmail(EmailTemplateEnum.RESETPASSWORD_CODE_EMAIL_HTML.getSubject(),
                        EmailTemplateEnum.RESETPASSWORD_CODE_EMAIL_HTML.set(captcha),
                        hashKey.split(":")[3])) {
                    throw new RuntimeException("发送邮件失败");
                }
            }
        }
    }

}
